﻿using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;

namespace Instrument
{
    public class DataHandler
    {
        private readonly ProductionMeasure _productionMeasure;//产品测试分析
        private List<byte> Buffer = new List<byte>();//串口数据缓存
        public delegate void MeasuringPrompt();
        /// <summary>
        /// 测试间隔提醒事件
        /// </summary>
        public event MeasuringPrompt MeasuringPromptEvent;

        public delegate void Clear(bool flag);
        /// <summary>
        /// 清零情况反馈事件
        /// </summary>
        public event Clear ClearEvent;
        double[] ZeroData;//放置零点数据

        bool LastALLBrokenFlag = true;//指示上一轮数据通道是否全断路
        bool ZeroTest = true;//指示是否正在进行清零测试

        public DataHandler(ProductionMeasure productionMeasure)
        {
            _productionMeasure = productionMeasure;
        }
        public void AnalyzeData(object senser , SerialDataReceivedEventArgs e)
        {
            SerialPort com = (SerialPort)senser;
            
            Byte[] ReceivedData = new Byte[com.BytesToRead];//创建接收字节数组
            com.Read(ReceivedData, 0, ReceivedData.Length);//读取所接收到的数据  
            Buffer.AddRange(ReceivedData);
            string SingleRow = FindSingleRow(Buffer);
            if (SingleRow == null)
                return;
            string[] SingleRowArray = SplitStringByComma(SingleRow);

            /*清零测试模块*/
            if (ZeroTest == true)
            {
                double[] zeroValue = AnalyzeSingleRowStringForClear(SingleRowArray);
                bool flag = JugdeZero(zeroValue);
                if (flag)
                {
                    ZeroData = zeroValue;
                    ZeroTest = false;
                }
                else
                {
                    ZeroData = null;
                }
                ClearEvent?.Invoke(flag);
                return;
            }


            double[] rowValue = AnalyzeSingleRowString(SingleRowArray);

            if (JudgeCircuitBroken(rowValue))
            {
                LastALLBrokenFlag = true;
                _productionMeasure.MeasureFlag = false;
                MeasuringPromptEvent?.Invoke();
                return;
            }
            else
            {
                if (LastALLBrokenFlag == true)
                {
                    if (JugeTwoChannelPrepared(rowValue) == true)
                    {
                        LastALLBrokenFlag = false;
                        _productionMeasure.MeasureFlag = true;
                        return;
                    }
                }
            }
            

            _productionMeasure.Add(rowValue);
        }
        /// <summary>
        /// 从缓存中查找单行数据
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns>字符串形式表示的单行数据</returns>
        private string FindSingleRow(List<byte> bytes)
        {
            string returnString = "";
            int count = 1;
            byte lastbyte = 0;
            byte[] temp; 
            foreach(var item in bytes)
            {
                if(item == 0x0A && lastbyte == 0x0D)
                {
                    temp = new byte[count - 2];
                    bytes.CopyTo(0, temp, 0, count - 2);
                    returnString = Encoding.ASCII.GetString(temp);
                    bytes.RemoveRange(0, count);
                    return returnString;
                }
                lastbyte = item;
                count++;
            }
            return null;
        }
        /// <summary>
        /// 将一维字符串数组转换成一维浮点数组(测试专用)
        /// </summary>
        /// <param name="StringArray"></param>
        /// <returns></returns>
        private double[] AnalyzeSingleRowString(string[] StringArray)
        {
            double[] rowValue = new double[_productionMeasure._production.ResistanceCount];
            for(int i = 0;i < rowValue.Length;i++)
            {
                rowValue[i] = StringArray[i].Equals("+9.90000000E+37") ? -1: (Convert.ToDouble(StringArray[i]) - ZeroData[i]);
            }
            return rowValue;
        }
        /// <summary>
        /// 将一维字符串数组转换成一维浮点数组(清零专用)
        /// </summary>
        /// <param name="StringArray"></param>
        /// <returns></returns>
        private double[] AnalyzeSingleRowStringForClear(string[] StringArray)
        {
            double[] rowValue = new double[_productionMeasure._production.ResistanceCount];
            for (int i = 0; i < rowValue.Length; i++)
            {
                rowValue[i] = StringArray[i].Equals("+9.90000000E+37") ? -1 : Convert.ToDouble(StringArray[i]);
            }
            return rowValue;
        }
        /// <summary>
        /// 检测通道是否全断路
        /// </summary>
        /// <param name="DoublegArray"></param>
        /// <returns></returns>
        private bool JudgeCircuitBroken(double[] DoublegArray)
        {
            foreach(var item in DoublegArray)
            {
                if(!(item == -1))
                {
                    return false;
                }
            }
            return true;
        }
        /// <summary>
        /// 用逗号切割字符串
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        private string[] SplitStringByComma(string s)
        {
            char[] comma = new char[_productionMeasure._production.ResistanceCount - 1];
            for (int i = 0; i < comma.Length; i++)
            {
                comma[i] = ',';
            }
            string[] temp = s.Split(comma);
            return temp;
        }
        /// <summary>
        /// 判断是否至少有三路通道已夹上电阻
        /// </summary>
        /// <param name="StringArray"></param>
        /// <returns></returns>
        private bool JugeTwoChannelPrepared(double[] StringArray)
        {
            int count = 0;
            foreach (var item in StringArray)
            {
                if (item != -1 && item > 1)
                {
                    count++;
                }
            }
            if (count > 2)
            {
                return true;
            }
            else
                return false;
        }
        /// <summary>
        /// 检查清零数据
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        private bool JugdeZero(double[] m)
        {
            foreach(var item in m)
            {
                if (item < 1 && item >= 0)
                    continue;
                else
                    return false;
            }
            return true;
        }
    }
}
